package plugin

import (
	"encoding/base64"
	"encoding/hex"
	"gitee.com/injoyai/goutil/conv"
	"gitee.com/injoyai/goutil/maps"
	"gitee.com/injoyai/goutil/script"
	"time"
)

var (
	cacheMap *maps.Safe
)

// funcGetJson 获取json数据
func funcGetJson(args *script.Args) interface{} {
	return conv.NewMap(args.GetString(1)).GetString(args.GetString(2))
}

// funcBase64Encode base64编码
func funcBase64Encode(args *script.Args) interface{} {
	data := args.GetString(1)
	return base64.StdEncoding.EncodeToString([]byte(data))
}

// funcBase64Decode base64解码
func funcBase64Decode(args *script.Args) interface{} {
	data := args.GetString(1)
	bs, _ := base64.StdEncoding.DecodeString(data)
	return string(bs)
}

// funcHexToBytes 字符转字节 例 "0102" >>> []byte{0x01,0x02}
func funcHexToBytes(args *script.Args) interface{} {
	s := args.GetString(1)
	bs, _ := hex.DecodeString(s)
	return string(bs)
}

// funcHexToString 字节转字符 例 []byte{0x01,0x02} >>> "0102"
func funcHexToString(args *script.Args) interface{} {
	return hex.EncodeToString(args.GetBytes(1))
}

// funcGetCache 获取缓存
func funcGetCache(args *script.Args) interface{} {
	if cacheMap == nil {
		cacheMap = maps.NewSafe()
	}
	return cacheMap.MustGet(args.GetString(1))
}

// funcSetCache 设置缓存
func funcSetCache(args *script.Args) interface{} {
	if cacheMap == nil {
		cacheMap = maps.NewSafe()
	}
	key := args.GetString(1)
	val := args.GetString(2)
	expiration := args.GetInt(3, 0)
	cacheMap.Set(key, val, time.Millisecond*time.Duration(expiration))
	return nil
}

// funcLen 取字符长度
func funcLen(args *script.Args) interface{} {
	key := args.GetString(1)
	return len(key)
}

// funcToInt 任意类型转int
func funcToInt(args *script.Args) interface{} {
	return conv.Int(args.GetString(1))
}

// funcToInt8 任意类型转int8
func funcToInt8(args *script.Args) interface{} {
	return conv.Int8(args.GetString(1))
}

// funcToInt16 任意类型转int16
func funcToInt16(args *script.Args) interface{} {
	return conv.Int16(args.GetString(1))
}

// funcToInt32 任意类型转int32
func funcToInt32(args *script.Args) interface{} {
	return conv.Int32(args.GetString(1))
}

// funcToInt64 任意类型转int64
func funcToInt64(args *script.Args) interface{} {
	return conv.Int64(args.GetString(1))
}

// funcToUint8 任意类型转uint8
func funcToUint8(args *script.Args) interface{} {
	return conv.Uint8(args.GetString(1))
}

// funcToUint16 任意类型转uint8
func funcToUint16(args *script.Args) interface{} {
	return conv.Uint16(args.GetString(1))
}

// funcToUint32 任意类型转uint32
func funcToUint32(args *script.Args) interface{} {
	return conv.Uint32(args.GetString(1))
}

// funcToUint64 任意类型转uint64
func funcToUint64(args *script.Args) interface{} {
	return conv.Uint32(args.GetString(1))
}

// funcToFloat 任意类型转浮点
func funcToFloat(args *script.Args) interface{} {
	return conv.Float64(args.GetString(1))
}

// funcToFloat32 任意类型转浮点32位
func funcToFloat32(args *script.Args) interface{} {
	return conv.Float32(args.GetString(1))
}

// funcToFloat64 任意类型转浮点64位
func funcToFloat64(args *script.Args) interface{} {
	return conv.Float64(args.GetString(1))
}

// funcToString 任意类型转字符串
func funcToString(args *script.Args) interface{} {
	return args.GetString(1)
}

// funcToBool 任意类型转bool
func funcToBool(args *script.Args) interface{} {
	return conv.Bool(args.GetString(1))
}

// funcToBIN 数字转成2进制字符串
func funcToBIN(args *script.Args) interface{} {
	byte := args.GetInt(2)
	data := interface{}(args.GetInt64(1))
	switch byte {
	case 1:
		data = conv.Uint8(data)
	case 2:
		data = conv.Uint16(data)
	case 4:
		data = conv.Uint32(data)
	case 8:
		data = conv.Uint32(data)
	default:
		data = conv.Uint16(data)
	}
	return conv.BINStr(data)
}

// funcGetByte 获取字符串的字节 ascii
func funcGetByte(args *script.Args) interface{} {
	s := args.GetString(1)
	idx := args.GetInt(2)
	if len(s) > idx {
		return s[idx]
	}
	return 0
}

// funcSum 校验和
func funcSum(args *script.Args) interface{} {
	sum := 0
	for _, v := range args.Args {
		sum += v.Int()
	}
	return sum
}

// funcAddByte 加减字节
func funcAddByte(args *script.Args) interface{} {
	s := args.GetString(1)
	add := int16(args.GetInt(2))
	result := []byte(nil)
	for _, v := range []byte(s) {
		result = append(result, byte(int16(v)+add))
	}
	return string(result)
}
